<template>
  <!-- 挂载容器 -->
  <div>
    <div ref="vue"></div>
    <div ref="react"></div>
  </div>
</template>

<script>
  import Vue from "vue";
  import Component from "vue-class-component";

  let React = null;

  @Component({
    props: {
      // 组件地址
      url: {
        type: String,
        required: true
      },
      // 传递给组件的初始数据
      propsData: {
        type: Object,
        default: () => {}
      }
    },
    watch: {
      url: {
        handler: function(url, oldUrl) {
          if (url) {
            console.log(url);
            this.componentAdapter();
          }
        }
      }
    }
  })
  export default class ReactLoader extends Vue {
    errorMessage = "";

    /**
     * 是 Vue 还是 React?
     */
    componentAdapter() {
      const ext = this.url.split(".").pop();
      switch (ext) {
        case "vue":
          let classNameTrans = `vue-${this.url}`.replace(/\/|\./g, "-");
          this.$refs.vue.innerHTML = `<div class="${classNameTrans}"></a>`;
          this.$refs.react.style.display = "none";
          import(`@components/${this.url}`).then(m => {
            const Component = Vue.extend(m.default);
            new Component({
              propsData: this.propsData
            }).$mount(document.querySelector(`.${classNameTrans}`));
          });
          this.$refs.vue.style.display = `block`;
          break;
        case "jsx":
          this.importReactComponent();
        default:
          break;
      }
    }

    // 按需载入react运行库
    async importReactRuntime() {
      if (!React) {
        try {
          const m = await import("react");
          React = m.default;
        } catch (e) {
          return Promise.reject(e);
        }
      }
      return Promise.resolve();
    }

    // 载入React组件
    async importReactComponent() {
      await this.importReactRuntime();
      try {
        // let classNameTrans = `react-${this.url}`.replace(/\/|\./g, "-");
        // this.$refs.container.innerHTML = `<div class="${classNameTrans}"></a>`;
        this.$refs.vue.style.display = `none`;
        const m = await import(`@components/${this.url}`);
        React.render(
          React.createElement(m.default, { propsData: this.propsData }),
          this.$refs.react
        );
        this.$refs.react.style.display = `block`;
      } catch (e) {
        this.errorMessage = "加载失败";
        throw new Error(e);
      }
    }

    mounted() {
      this.componentAdapter();
    }
  }
</script>
